package com.sanmao5.wecom.api.token;

import com.sanmao5.wecom.cache.WeComTokenCacheable;
import com.sanmao5.wecom.object.AgentDetail;
import lombok.AllArgsConstructor;
import lombok.Getter;

/**
 * 抽象访问令牌API
 *
 * @author 黄侯淳
 * @since JDK 1.8
 */
@AllArgsConstructor
@Getter
public abstract class AbstractTokenApi implements TokenApi {

    /**
     * 访问令牌缓存
     */
    private final WeComTokenCacheable wecomTokenCacheable;

    /**
     * 应用详情
     */
    private final AgentDetail agentDetail;

    /**
     * 获取访问令牌
     *
     * @return 访问令牌
     */
    @Override
    public final String getToken() {
        final String corpId = agentDetail.getCorpId();
        final String agentId = agentDetail.getAgentId();
        String accessToken;
        if (wecomTokenCacheable != null) {
            accessToken = wecomTokenCacheable.getAccessToken(corpId, agentId);
            if (accessToken == null) {
                synchronized (this) {
                    accessToken = wecomTokenCacheable.getAccessToken(corpId, agentId);
                    if (accessToken == null) {
                        accessToken = wecomTokenCacheable.putAccessToken(corpId, agentId, doGetToken(agentDetail));
                    }
                }
            }
        } else {
            accessToken = doGetToken(agentDetail);
        }
        return accessToken;
    }

    @Override
    public void clearToken() {
        if (wecomTokenCacheable != null) {
            wecomTokenCacheable.clearAccessToken(agentDetail.getCorpId(), agentDetail.getAgentId());
        }
    }

    /**
     * 执行获取访问令牌的具体逻辑
     *
     * @param agentDetail 应用详情
     * @return 访问令牌
     */
    protected abstract String doGetToken(AgentDetail agentDetail);
}
